﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;

namespace URF.Core.Abstractions
{
  public interface IRepository<TEntity> where TEntity : class
  {
    Task<TEntity> FindAsync(object[] keyValues, CancellationToken cancellationToken = default);
    Task<TEntity> FindAsync<TKey>(TKey keyValue, CancellationToken cancellationToken = default);
    Task<bool> ExistsAsync(object[] keyValues, CancellationToken cancellationToken = default);
    Task<bool> ExistsAsync<TKey>(TKey keyValue, CancellationToken cancellationToken = default);
    Task LoadPropertyAsync(TEntity item, Expression<Func<TEntity, object>> property, CancellationToken cancellationToken = default);
    void Attach(TEntity item);
    void Detach(TEntity item);
    void Insert(TEntity item);
    void Update(TEntity item);
    void Delete(TEntity item);
    Task<bool> DeleteAsync(object[] keyValues, CancellationToken cancellationToken = default);
    Task<bool> DeleteAsync<TKey>(TKey keyValue, CancellationToken cancellationToken = default);
    IQueryable<TEntity> Queryable();
    IQueryable<TEntity> QueryableSql(string sql, params object[] parameters);
    IQuery<TEntity> Query();
    IQuery<TEntity> Query(IQueryObject<TEntity> queryObject);
    IQuery<TEntity> Query(Expression<Func<TEntity, bool>> query);
  }
}
